home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Prog / U-Z / VideoToolBox Folder / VideoToolboxSources / nrand.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-23  |  2.7 KB  |  83 lines  |  [TEXT/KAHL]

  1. /*
  2. nrand.c
  3. nrand(n), nrandU(), and nrandUL(n)  all return a random integer in range [0, n-1], 
  4. where n must be greater than zero. nrand() and nrandU() are faster, but nrandUL() 
  5. has a much larger domain and range: unsigned long.
  6.  
  7. nrand() is now obsolete, retained solely for backward compatibility. I suggest that 
  8. all programs use nrandU() instead, which uses exactly the same code, but is now 
  9. properly declared as accepting and returning an unsigned short.(Changing the type 
  10. of nrand's returned value at this late date might have adversely affected existing 
  11. programs.)
  12. HISTORY:
  13. 4/29/88    dgp    wrote it.
  14. 3/19/90    dgp    made it portable between THINK C and MPW C.
  15. 8/24/91 dgp    removed unnecessary (long) in preprocessor statement, since keywords
  16.             are undefined at preprocessor time in ANSI C.
  17. 10/21/91 dgp Removed obsolete inclusion of MacProto.h.
  18. 9/13/92    dgp    Changed nrand's argument type from int to short, since the algorithm assumes
  19.             that the argument is a short.
  20.             Using THINK C's Disassembler I noticed that I could substantially speed
  21.             up the code, replacing the long division by a bit shift. The answers for 
  22.             legal values of n, i.e. n>0, are unchanged, but the answers for values of 
  23.             n outside that range have changed because I now explicitly cast n
  24.             to unsigned long rather than long. (Bit shifting and division give different
  25.             answers when the numerator is negative.)
  26.             Added nrandU() and nrandUL().
  27. 9/18/92    dgp    Cast nrand() from int to unsigned short to prompt THINK C to generate 
  28.             tighter code.
  29. */
  30. #include "VideoToolbox.h"
  31. #include <assert.h>
  32.  
  33. #if RAND_MAX > LONG_MAX/SHRT_MAX
  34.     #error "nrand() assumes that a long can hold the product of short & rand()."
  35. #endif
  36.  
  37. int nrand(short n)
  38. {
  39.     #if RAND_MAX+1L==0x8000
  40.         return (unsigned long)n*rand()>>15;
  41.     #else
  42.         return (unsigned long)n*rand()/(RAND_MAX+1L);
  43.     #endif
  44. }
  45. /*
  46. nrand:
  47. 00000000        LINK      A6,#$0000
  48. 00000004        JSR       $0000(A5)
  49. 00000008        MULS.W    $0008(A6),D0
  50. 0000000C        MOVEQ     #$0F,D1
  51. 0000000E        LSR.L     D1,D0
  52. 00000010        UNLK      A6
  53. 00000012        RTS
  54. */
  55.  
  56. #if RAND_MAX > ULONG_MAX/USHRT_MAX
  57.     #error "nrandU() assumes that an unsigned long can hold the product of unsigned short & rand()."
  58. #endif
  59.  
  60. unsigned short nrandU(unsigned short n)
  61. {
  62.     #if RAND_MAX+1L==0x8000
  63.         return (unsigned long)n*(unsigned short)rand()>>15;
  64.     #else
  65.         return (unsigned long)n*(unsigned short)rand()/(RAND_MAX+1L);
  66.     #endif
  67. }
  68. /*
  69. nrandU:
  70. 00000000        LINK      A6,#$0000
  71. 00000004        JSR       $0000(A5)
  72. 00000008        MULU.W    $0008(A6),D0
  73. 0000000C        MOVEQ     #$0F,D1
  74. 0000000E        LSR.L     D1,D0
  75. 00000010        UNLK      A6
  76. 00000012        RTS
  77. */
  78.  
  79. unsigned long nrandUL(unsigned long n)
  80. {
  81.     return (unsigned long)((double)n*randUL()/(ULONG_MAX+1.0)); 
  82. }
  83.